package xyz.ddlnt.commonutil.handler;


import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import xyz.ddlnt.commonutil.enumeration.ResultCode;
import xyz.ddlnt.commonutil.exception.GlobalException;
import xyz.ddlnt.commonutil.result.Result;

import java.nio.file.AccessDeniedException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 全局异常处理类
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * @description: 全局异常处理方法
     * @param: e
     * @return: cn.edu.zzuli.common.result.Result
     */
//    @ExceptionHandler(Exception.class)
//    @ResponseBody
//    public Result error(Exception e){
//        e.printStackTrace();
//        log.error("全局异常处理: {}", e.getMessage(), e);
//        log.error("原因: ", e.getCause());
//        return Result.fail();
//    }

    /**
     * @description: 自定义异常处理方法
     * @param: e
     * @return: cn.edu.zzuli.common.result.Result
     */
    @ExceptionHandler(GlobalException.class)
    @ResponseBody
    public Result error(GlobalException e){
        e.printStackTrace();
        log.error("自定义异常处理: {}", e.getMessage(), e);
        log.error("原因: ", e.getCause());
        return Result.fail(e.getCode(), e.getMessage());
    }

    /**
     * @description: 非法参数异常处理
     * @param: e
     * @return: cn.edu.zzuli.common.result.Result
     */
    @ExceptionHandler({IllegalArgumentException.class})
    @ResponseBody
    public Result llegalArgumentException(IllegalArgumentException e) {
        log.error("非法参数异常处理: {}", e.getMessage(), e);
        return Result.fail( ResultCode.ARGUMENT_VALID_ERROR);
    }

    /**
     * @description: 访问被拒绝异常处理
     * @param: e
     * @return: cn.edu.zzuli.common.result.Result
     */
    @ExceptionHandler(AccessDeniedException.class)
    @ResponseBody
     public Result error(AccessDeniedException e){
        log.error("访问被拒绝异常处理: {}", e.getMessage(), e);
        return Result.fail(ResultCode.PERMISSION_DENIED);
     }

    /**
     * @description: 方法参数无效异常处理
     * @param: exception
     * @return: cn.edu.zzuli.common.result.Result
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public Result<Map<String, Object>> error(MethodArgumentNotValidException exception) {
        BindingResult result = exception.getBindingResult();
        Map<String, Object> errorMap = new HashMap<>();
        List<FieldError> fieldErrors = result.getFieldErrors();
        fieldErrors.forEach(error -> {
            log.error("字段验证错误: {}, msg:{}", error.getField(), error.getDefaultMessage());
            errorMap.put(error.getField(), error.getDefaultMessage());
        });
        return Result.fail(ResultCode.ARGUMENT_VALID_ERROR, errorMap);
    }
}
